package service

import (
	"fmt"
	"go-project/common"
	"go-project/common/casbininit"
	"go-project/dto/requrest"
	"go-project/dto/response"
	"go-project/models"
)

type Admin struct {
}

func (Admin) FindAdmins(admin_search_req *requrest.AdminSearchRequest) (lists []response.AdminList, count int64, err error) {
	offset := (admin_search_req.Pagination.Page - 1) * admin_search_req.Pagination.Limit
	var admin_model *models.Admin
	query := common.DB.Table(admin_model.TableName())
	if len(admin_search_req.Username) > 0 {
		query = query.Where("username like ?", fmt.Sprintf("%%%s%%", admin_search_req.Username))
	}
	if len(admin_search_req.Email) > 0 {
		query = query.Where("email like ?", fmt.Sprintf("%%%s%%", admin_search_req.Email))
	}
	if len(admin_search_req.Phone) > 0 {
		query = query.Where("phone like ? ", fmt.Sprintf("%%%s%%", admin_search_req.Phone))
	}
	query.Model(admin_model).Select("count(id)").Count(&count)
	err = query.Select("admins.id,admins.username,admins.created_at,admins.email,admins.role_id,admins.phone,admins.last_login_at,admins.login_ip,roles.name as role_name,roles.id").Limit(admin_search_req.Pagination.Limit).Joins("left join roles on roles.id = admins.role_id").Order("admins.id desc").Offset(offset).Where("admins.deleted_at IS NULL").Scan(&lists).Error
	return
}
func (Admin) Add(admin_insert_request *requrest.AdminInsertRequest) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}

	var role models.Roles
	err := common.DB.Where("`key`=?", admin_insert_request.Role).First(&role).Error
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	var admin models.Admin
	admin_insert_request.Generate(&admin)
	admin.RoleId = role.ID
	result := common.DB.Create(&admin)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	_, err = casbininit.Enforcer.DeleteRolesForUser(admin.Username)
	_, err = casbininit.Enforcer.AddRoleForUser(admin.Username, "role:"+admin_insert_request.Role)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return admin.ID, tx.Commit().Error
}

func (Admin) Update(admin_update_request *requrest.AdminUpdateRequest) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var model models.Admin
	row := common.DB.First(&model, admin_update_request.AdminId)
	if err := row.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	var role models.Roles
	err := common.DB.Where("`key`=?", admin_update_request.Role).First(&role).Error
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	admin_update_request.Generate(&model)
	model.RoleId = role.ID
	result := common.DB.Save(&model)

	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	_, err = casbininit.Enforcer.DeleteRolesForUser(model.Username)
	_, err = casbininit.Enforcer.AddRoleForUser(model.Username, "role:"+admin_update_request.Role)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return model.ID, tx.Commit().Error
}
func (Admin) Del(id uint) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var model models.Admin
	result := common.DB.Delete(&model, id)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	_, err := casbininit.Enforcer.DeleteRolesForUser(model.Username)
	if err != nil {
		tx.Rollback()
		return 0, err
	}
	return uint(result.RowsAffected), tx.Commit().Error
}
func (Admin) Get(id uint) (models.Admin, error) {
	var model models.Admin
	result := common.DB.First(&model, id)
	return model, result.Error
}

func (Admin) BatchDelByIds(ids []int) (uint, error) {
	// 开始事务
	tx := common.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	if err := tx.Error; err != nil {
		return 0, err
	}
	var adminModels []models.Admin
	var model models.Admin
	result := common.DB.Model(&model).Find(&adminModels, ids)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	result = common.DB.Delete(&model, ids)
	if err := result.Error; err != nil {
		tx.Rollback()
		return 0, err
	}
	for _, adminModel := range adminModels {
		_, err := casbininit.Enforcer.DeleteRolesForUser(adminModel.Username)
		if err != nil {
			tx.Rollback()
			return 0, err
		}
	}
	return uint(result.RowsAffected), tx.Commit().Error
}

func (Admin) DistributeRole(adminDistributeRoleRequest *requrest.AdminDistributeRoleRequest) (err error) {
	var model models.Admin
	err = common.DB.First(&model, adminDistributeRoleRequest.AdminId).Error
	if err != nil {
		return err
	}
	var role models.Roles
	err = common.DB.Where("`key`=?", adminDistributeRoleRequest.Role).First(&role).Error
	if err != nil {
		return err
	}
	common.DB.Model(&model).Update("role_id", role.ID)
	_, err = casbininit.Enforcer.DeleteRolesForUser(model.Username)
	_, err = casbininit.Enforcer.AddRoleForUser(model.Username, "role:"+adminDistributeRoleRequest.Role)
	return
}
